from selenium import webdriver
import time
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

# 防止反爬
def anit_crawler():
    # 反爬处理
    # 浏览器配置对象
    options = webdriver.ChromeOptions()
    # 关闭受控提示
    options.add_experimental_option("excludeSwitches", ["enable-automation"])
    options.add_experimental_option("useAutomationExtension", False)
    # 禁用浏览器通知、麦克风和摄像头权限的提示框, 保存密码提示框
    options.add_experimental_option("prefs", {
        "profile.default_content_setting_values.notifications": 2,
        "profile.default_content_setting_values.media_stream_mic": 2,
        "profile.default_content_setting_values.media_stream_camera": 2,
        'credentials_enable_service': False,
        'profile.password_manager_enabled': False,
    })
    # 反爬虫特征处理
    options.add_argument('--disable-blink-features=AutomationControlled')
    # options.add_argument("--disable-features=MicrosoftAccount")
    # options.add_argument("--disable-sync-notification")
    # options.add_argument("--disable-sync")
    # options.add_argument("--inprivate")  # 匿名窗口登录
    print("反爬处理结束")
    return options


# 登录功能
def login_fun(driver, login_url):
    # 浏览器发送请求
    driver.get(login_url)

    # 进入iframe
    driver.switch_to.frame(0)

    # 定位元素切换到账号密码输入
    driver.find_element(By.XPATH, '//a[@class="password-login-link"]').click()
    """
    find_element()
    功能：driver对象的方法，查找网页中的元素
    参数：1、指定查找方式 2、语法
    返回值：WebElement元素对象
    """
    # 定位账号密码的input元素，输入账号密码
    driver.find_element(By.ID, 'fm-login-id').send_keys('你自己的账号')
    driver.find_element(By.ID, 'fm-login-password').send_keys('你自己的密码')
    # 定义行为链
    try:
        time.sleep(0.5)
        driver.switch_to.frame(0)

        slider = driver.find_element(By.XPATH, '//span[@id="nc_1_n1z"]')

        # 1、初始化一个行为链对象
        actions = ActionChains(driver)
        # 2、定义行为
        actions.click_and_hold(slider)  # 点击并拖拽元素
        actions.move_by_offset(1170, 0)  # 向右拖拽1115像素
        actions.release()  # 松开鼠标

        # 3、执行行为链
        actions.perform()  # 执行所有ActionChains中的事件

        time.sleep(0.5)
        # 点击登录
        driver.find_element(By.XPATH, '//button[@type="submit"]').click()
    except:
        # 点击登录
        driver.find_element(By.XPATH, '//button[@type="submit"]').click()
    finally:
        time.sleep(2)  # 防止登录过快
        print("登录账号结束")


# 买票下单
def buy_tickets(driver, target_url):

    while True:
        # 请求买票页面
        driver.get(target_url)
        try:
            time.sleep(1)
            # 点击知道了
            WebDriverWait(driver, 3).until(
                EC.presence_of_element_located((By.XPATH, '//div[@class="content"]/div[@class="button"]'))
            ).click()
        except:
            print('没有弹窗“知道了”')

        # 进行购买
        WebDriverWait(driver, 3).until(
            EC.presence_of_element_located((By.XPATH, '//div[@class="buy__button"]'))
        ).click()

        # 等待选择时间的界面出现
        WebDriverWait(driver, 3).until(
            EC.presence_of_element_located((By.XPATH, '//div[@class="sku-content"]/div'))
        )
        # 选择时间
        # element_list1 = driver.find_elements(By.XPATH, '//div[@class="sku-content"]/div')
        # element_list1[0].click()

        # 等待票价的出现
        WebDriverWait(driver, 3).until(
            EC.presence_of_element_located((By.XPATH, '//div[contains(@class, "sku-tickets-card")]/div[2]/div'))
        )

        # 选择票价
        element_list2 = driver.find_elements(By.XPATH, '//div[contains(@class, "sku-tickets-card")]/div[2]/div')
        element_list2[1].click()

        try:
            # 等待点击购买的按键亮起
            WebDriverWait(driver, 3).until(
                EC.presence_of_element_located((By.XPATH, '//div[@class="sku-footer-bottom"]/div[position()=last()]'))
            ).click()
            print('点击购买成功')
            time.sleep(3)
            break
        except:
            print('点击购买失败')


# 确认订单
def confirm_order(driver):
    try:
        print(driver.title)
        # 等待观影人选择按钮出现并点击选择观影人
        WebDriverWait(driver, 10).until(
            EC.presence_of_element_located((By.CSS_SELECTOR, '.iconfont.icondanxuan-weixuan_'))
        ).click()
        print("观影人选择成功")
    except:
        print("观影人选择失败")
    # # 点击提交订单
    # WebDriverWait(driver, 10).until(
    #     EC.presence_of_element_located((By.LINK_TEXT, '提交订单'))
    # ).click()


def main():
    # 定义URL
    base_url = "https://m.damai.cn/damai/home/index.html"
    # target_url = "https://m.damai.cn/damai/detail/item.html?itemId=721216860314&spm=a2o71.search.list.ditem_0&sqm=dianying.h5.unknown.value"  # 五月天
    target_url = "https://m.damai.cn/damai/detail/item.html?itemId=720545258599&spm=a2o71.category.itemlist.ditem_0"  # 汪峰
    login_url = "https://m.damai.cn/damai/minilogin/index.html"

    # 进行反爬处理
    options = anit_crawler()
    # 实例化driver
    driver = webdriver.Chrome(options=options)
    # 将webdriver属性置空，实现反爬
    driver.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument', {
        'source': 'Object.defineProperty(navigator, "webdriver", {get: () => undefined})'
    })

    # 登录账号
    login_fun(driver, login_url)
    # 选择票
    buy_tickets(driver, target_url)
    # 订单确认
    confirm_order(driver)

    input('>>>')
    # 退出浏览器
    driver.quit()


if __name__ == '__main__':
    main()
